#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>


#define NUM 1024


struct MYFILE_
{
    int fd;
    char buffer[1024];
    int end; // 当前缓冲区的结尾
};



typedef struct MYFILE_ MYFILE;


MYFILE *fopen_(const char *pathname, const char *mode)
{
    assert(pathname);
    assert(mode);

    MYFILE *fp = NULL;

    if (strcmp(mode, "r") == 0)
    {
        
    }
    else if (strcmp(mode, "r+") == 0)
    {

    }
    else if (strcmp(mode, "w") == 0)
    {
        int fd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0666);

        if (fd >= 0)
        {
            fp = (MYFILE*)malloc(sizeof(MYFILE));
            memset(fp, 0, sizeof(MYFILE));
            fp->fd = fd;
        }
    }
    else if (strcmp(mode, "w+") == 0)
    {

    }
    else if (strcmp(mode, "a") == 0)
    {

    }
    else if (strcmp(mode, "a+") == 0)
    {

    }
    else 
    {
        // 什么都不用做
    }
}


void fputs_(const char *message, MYFILE *fp)
{
    assert(message);
    assert(fp);

    strcpy(fp->buffer + fp->end, message); // abcd\0
    fp->end += strlen(message);

    // for debug
    printf("%s\n", fp->buffer);


    if (fp->fd == 1)
    {
        // 标准输出
        if (fp->buffer[fp->end - 1] == '\n')
        {
            // fprintf(stderr, "fflush: %s", fp->buffer);
            write(fp->fd, fp->buffer, fp->end);
            fp->end = 0;
        }
    }
    else if (fp->fd == 2)
    {
        // 标准错误
    }
    else 
    {
        // 其他文件
    }
}



void fflush_(MYFILE *fp)
{
    assert(fp);

    if (fp->end != 0)
    {
        // 暂且认为刷新了... 其实是把数据写到了内核中
        write(fp->fd, fp->buffer, fp->end);
        syncfs(fp->fd); // 将数据写入到磁盘中
        fp->end = 0;
    }
}




void fclose_(MYFILE *fp)
{
    assert(fp);
    fflush_(fp);
    close(fp->fd);
    free(fp);
}




int main()
{
    // close(1)
    MYFILE *fp = fopen_("./mylog.txt", "w");
    if (fp == NULL)
    {
        printf("open file error\n");
        return 1;
    }

    fputs_("one: hello world", fp);


    fork();

    fclose_(fp);
    
    return 0;
}
